package net.xiaosaguo.mymall.search.thread;

import lombok.SneakyThrows;

import java.util.concurrent.*;

/**
 * description: 多线程测试
 *
 * @author xiaosaguo
 * @date 2020/07/02
 */
public class ThreadTest {

    // 获取线程池，保证系统中的线程池应该只有一两个，每个异步任务直接提交给线程池
    public static ExecutorService threadPool = Executors.newFixedThreadPool(10);

    @SneakyThrows
    public static void main(String[] args) {
        System.out.println("main...start...");
        /*
         * 1. 继承 Thread
         * 2. 实现 Runnable 接口
         * 3. 实现 Callable 接口
         * 4. 线程池[ExecutorService]
         *      给线程池提交任务
         *      new Thread(() -> System.out.println("hello")).start();
         *      1. 创建
         *          1. Executors
         *          2. new ThreadPoolExecutor()
         *
         *
         * 区别：
         * 1/2 不能得到返回值，3可以得到返回值
         * 1/2/3不能控制资源，4个可以控制资源，性能稳定
         */
        Thread01 thread01 = new Thread01();
        thread01.start();

        Runnable02 runnable02 = new Runnable02();
        new Thread(runnable02).start();

        Callable03 callable03 = new Callable03();
        FutureTask<Integer> futureTask = new FutureTask<>(callable03);
        new Thread(futureTask).start();
        Integer integer = futureTask.get();
        System.out.println(integer);

        // 开销大，消耗资源
        new Thread(() -> System.out.println("hello")).start();
        threadPool.execute(new Runnable02());

        // 原生创建线程池
        /*
         * 线程池的 7 大参数
         * public ThreadPoolExecutor(
         *
         * int corePoolSize,[5]
         * # 核心线程数[只要线程池不销毁一直存在，除非设置了allowCoreThreadTimeOut]；线程池，创建好以后就准备就绪的线程数据，
         * # 就等待来接受异步任务去执行（new Thread * 5）
         *
         * int maximumPoolSize,
         * # 最大线程数量，控制资源
         *
         * long keepAliveTime,
         * # 存活时间，当前线程数量大于corePoolSize时，等待新任务的时间，如果大于此时间就释放空闲线程
         *
         * TimeUnit unit,
         * # 时间单位
         *
         * BlockingQueue<Runnable> workQueue,
         * # 阻塞队列：如果任务有很多，就会将目前多的任务放在队列里面，主要有线程空闲，就会去队列里面取出新的任务去执行
         *
         * ThreadFactory threadFactory,
         * # 线程创建的工厂
         *
         * RejectedExecutionHandler handler
         * # 如果队列满了，按照指定的拒绝策略拒绝执行任务
         *
         * )
         *
         * 工作顺序：
         *
         *
         */
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
                5,
                200,
                10,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(10000),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy());

        System.out.println("main...end...");
    }

    public static class Thread01 extends Thread {
        @Override
        public void run() {
            System.out.println("当前线程01：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果01：" + i);
        }
    }

    public static class Runnable02 implements Runnable {
        @Override
        public void run() {
            System.out.println("当前线程02：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果02：" + i);
        }
    }

    public static class Callable03 implements Callable<Integer> {
        @Override
        public Integer call() throws Exception {
            System.out.println("当前线程03：" + Thread.currentThread().getId());
            int i = 10 / 2;
            System.out.println("运行结果03：" + i);
            return i;
        }
    }
}
